from odoo.http import request, Response
from odoo import http, Command
from odoo.addons.api_manager.tools.check_token import check_token
from odoo.addons.api_manager.tools.create_records import create_records
import logging
import json
from odoo import fields, _
from odoo.exceptions import ValidationError

_logger = logging.getLogger(__name__)


class ApiMrpProduction(http.Controller):

    @http.route("/v1.0/sb_api/mrp_enter/warehouse", auth='public', type='http', methods=['post'], csrf=False)
    @check_token
    def mrp_enter_warehouse(self, **kwargs):
        """成品入库
        1. 半成品 默认指定原始库存且没有批次号的情况下，去除关联的quant，并跳过半成品库存验证
        2. 入库良品 + 废品 = 入库总数。废品单独产生报废调拨
        """
        _logger.info('开始成品入库请求...')
        request.env.uid = 2
        data = request.httprequest.get_json()
        result = {
            'json': True,
            'data': {}
        }
        api_result = {
            'code': 0,
            'message': 'success'
        }
        try:
            product_list = data.get('params')
            for p in product_list:
                # params = data.get('params')
                production_code = p.get('production_code')
                product_code = p.get('product_code')
                qty = int(p.get('qty', 0))

                product_tmpl_id = request.env['product.template'].sudo().search([('default_code', '=', product_code)])
                if not product_tmpl_id:
                    raise ValidationError('未找到{}对应的产品'.format(product_code))

                production = request.env['mrp.production'].sudo().search(
                    [('name', '=', production_code), ('product_id', '=', product_tmpl_id.product_variant_id.id)])
                if not production:
                    raise ValidationError('未找到制造编码{}，产品编码{}, 对应的制造单'.format(production_code, product_code))

                qty_producing = qty
                if not qty:
                    raise ValidationError('成品入库数量必须大于0'.format(qty))
                if production.state != 'done':
                    raise ValidationError("Odoo入库失败, 制造单未完成:{}".format(production.state))

                picking_type = request.env['stock.picking.type'].search([('barcode', '=', 'INT-PRODUCTIONIN')], limit=1)
                origin = f'{product_tmpl_id.product_variant_ids[0].name} / {production.base_mo or ""}'
                finish_picking_id = request.env['stock.picking'].search([
                    ('picking_type_id', '=', picking_type.id),
                    ('origin', '=', origin),
                    ('state', 'not in', ('done', 'cancel'))
                ], limit=1)

                if not finish_picking_id:
                    raise ValidationError('未查询到需要处理的成品入库单')
                product_uom_qty = finish_picking_id.move_ids_without_package[0].product_uom_qty
                if product_uom_qty < qty_producing:
                    raise ValidationError(
                        'odoo成品入库最大允许数量：{}, 接收数量:{}'.format(product_uom_qty, qty))

                finish_picking_id.move_ids_without_package[0].quantity = qty_producing
                res = finish_picking_id.button_validate()
                # 创建欠单
                if type(res) == dict and res.get('res_model', '') == 'stock.backorder.confirmation':
                    confirmation = request.env['stock.backorder.confirmation'].with_context(button_validate_picking_ids=[finish_picking_id.id]).create({
                        'pick_ids': [(4, finish_picking_id.id)]
                    })
                    confirmation.process()
            # production.qty_producing = qty_producing
                # production._set_qty_producing()
                # # 没有批次号会失败，自动提出没有批次号的quant
                # move_raw_ids = production.move_raw_ids.filtered(lambda x : not x.lot_ids)
                # for move in move_raw_ids:
                #     move.move_line_ids = [Command.clear()]
                # production.with_context(skip_consumption=True).button_mark_done()
                # production.is_autocomplete = True

        except Exception as e:
            api_result['message'] = '{}'.format(e)
            api_result['code'] = -1
            request.env.cr.rollback()

        result['data'] = api_result
        result_json = json.dumps(result, ensure_ascii=False)
        create_records(result_json)
        return Response(result_json)

    @http.route("/v1.0/sb_api/mrp_scrap/register", auth='public', type='http', methods=['post'], csrf=False)
    @check_token
    def mrp_scrap_register(self, **kwargs):
        """
        压合登记报废
        {
            'params': {
                'production_name': 'QN-XX-001169-01-000',
                'workcenter_code': 'LAM13',
                'scrap_qty': 1,
                'scrap_set_qty': 1,
                'scrap_panel_qty': 0
            }
        }
        """
        request.env.uid = 2
        data = request.httprequest.get_json()
        result = {
            'json': True,
            'data': {}
        }
        api_result = {
            'code': 0,
            'message': 'success'
        }
        try:
            with request.env.cr.savepoint():
                params = data.get('params', {})
                production_name, workcenter_code = params.get('production_name'), params.get('workcenter_code')
                if not production_name:
                    raise ValidationError('缺少生产单号')
                if not workcenter_code:
                    raise ValidationError('缺少工序代码')
                production_id = request.env['mrp.production'].search([('name', '=', production_name)], limit=1)
                if not production_id:
                    raise ValidationError(f'生产单{production_name}, 不存在')
                workorder_ids = production_id.workorder_ids.filtered(lambda x: x.workcenter_id.code == workcenter_code)
                if not workorder_ids:
                    raise ValidationError(f'登记工序不存在，代码: {workcenter_code}')
                workorder_id = workorder_ids[0]

                scrap_qty, scrap_set_qty, scrap_panel_qty = int(params.get('scrap_qty', 0)), int(params.get('scrap_set_qty', 0)), int(params.get('scrap_panel_qty', 0))
                if not scrap_qty or scrap_qty > workorder_id.qty_wip:
                    raise ValidationError('报废PCS数必须大于0或者大于在线数量')
                if scrap_set_qty > workorder_id.qty_wip_set:
                    raise ValidationError('报废SET数大于在线SET数')
                if scrap_panel_qty > workorder_id.qty_wip_pnl:
                    raise ValidationError('报废PANEL数大于在线PANEL数')
                reason = request.env['scrap.reason'].search([('name', '=', '首工序登记不良品')], limit=1)
                if not reason:
                    reason = request.env['scrap.reason'].sudo().create({'name': '首工序登记不良品'})
                workorder_id.write({'s_scrap_ids': [(0, 0, {
                    'scrap_reason_id': reason.id,
                    'scrap_qty': scrap_qty,
                    'scrap_set_qty': scrap_set_qty,
                    'scrap_panel_qty': scrap_panel_qty
                })]})
                production_id.write({'s_registered': True})
                production_id.with_delay().scrap_warning()
        except Exception as e:
            error = e.args[0]
            api_result = {
                'code': -1,
                'message': error
            }
        result['data'] = api_result
        result_json = json.dumps(result, ensure_ascii=False)
        create_records(result_json)
        return Response(result_json)


